﻿/********************************************************
 * File : MessageBox
 * Version : 1.0.0.2
 * Author : Vito.K
 * E-mail : vito2015@live.com
 * Date：2013/8/2 15:46:42
 * Description :  
 * 	// code description here.
 * ChangedHistory :
 *      // no history.
 ********************************************************/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Vito.Csharp.Wpf.Controls
{
	internal sealed class MessageBoxModule : Window
	{
		#region Private static fields

		private static Style CTRL_BUTTON_STYLE = Button.StyleProperty.DefaultMetadata.DefaultValue as Style;
		private static readonly Brush DefaultTitleForeground = new SolidColorBrush( Color.FromArgb( 100, 45, 100, 160 ) );

		private static bool B_USED_CUSTOM_BRUSHES = false;
		private static MessageBoxCustomInfo MB_CUSTOMINFO;

		#endregion // Private static fields

		#region Dependency Properties

		public new static readonly DependencyProperty TitleProperty =
	DependencyProperty.Register( "Title", typeof( string ), typeof( MessageBoxModule ), new PropertyMetadata( "标题" ) );

		public static readonly DependencyProperty MessageProperty =
	DependencyProperty.Register( "Message", typeof( string ), typeof( MessageBoxModule ), new PropertyMetadata( "" ) );

		public static readonly DependencyProperty TitleForegroundProperty =
	DependencyProperty.Register( "TitleForeground", typeof( Brush ), typeof( MessageBoxModule ), new PropertyMetadata( DefaultTitleForeground ) );

		public static readonly DependencyProperty CtrlButtonCollectionProperty =
	DependencyProperty.Register( "CtrlButtonCollection", typeof( IList<Button> ), typeof( MessageBoxModule ), new PropertyMetadata( new List<Button>() /*{ new Button() { Content = "确定" }, new Button() { Content = "取消" } }*/ ) );

		#endregion // Dependency Properties

		#region ctors

		static MessageBoxModule()
		{
			DefaultStyleKeyProperty.OverrideMetadata( typeof( MessageBoxModule ), new FrameworkPropertyMetadata( typeof( MessageBoxModule ) ) );
		}

		public MessageBoxModule()
		{
			try
			{
				this.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
				this.AllowsTransparency = true;
				this.WindowStyle = System.Windows.WindowStyle.None;
				this.ShowInTaskbar = false;
				this.Topmost = true;
				this.MouseLeftButtonDown += ( o, e ) =>
				{
					this.DragMove();
				};

				//var aaa = Application.LoadComponent( new Uri( @"/Vito.Csharp.Wpf.Controls;component/Themes/Generic.xaml", UriKind.Relative ) );

				Resources.Source = new Uri( @"/Vito.Csharp.Wpf.Controls;component/Themes/Generic.xaml", UriKind.Relative );
				if ( Resources.Contains( "MessageBoxButtonStyle" ) )
				{
					MessageBoxModule.SetDefaultCtorButtonStyle( Resources["MessageBoxButtonStyle"] as Style );
				}


			}
			catch { }

		}

		#endregion // ctors

		#region Public Static Functions

		public static void SetDefaultCtorButtonStyle( Style buttonStyle )
		{
			CTRL_BUTTON_STYLE = buttonStyle;
		}

		public static void SetMessageBoxCustomDefine( MessageBoxCustomInfo mbCustomIf )
		{
			if ( !default( MessageBoxCustomInfo ).Equals( mbCustomIf ) )
			{
				MessageBoxModule.MB_CUSTOMINFO = mbCustomIf;
				MessageBoxModule.B_USED_CUSTOM_BRUSHES = true;
			}
			else
			{
				MessageBoxModule.MB_CUSTOMINFO = default( MessageBoxCustomInfo );
				MessageBoxModule.B_USED_CUSTOM_BRUSHES = false;
			}
		}

		public static void ResetMessageBoxCustomDefine()
		{
			CTRL_BUTTON_STYLE = Button.StyleProperty.DefaultMetadata.DefaultValue as Style;
			MB_CUSTOMINFO = default( MessageBoxCustomInfo );
			B_USED_CUSTOM_BRUSHES = false;
		}

		#region Show MessageBox Functions

		public static MessageBoxResult Show( string messageBoxText )
		{
			return Show( null, messageBoxText, "", MessageBoxButton.OK );
		}

		public static MessageBoxResult Show( string messageBoxText, string caption )
		{
			return Show( null, messageBoxText, caption, MessageBoxButton.OK );
		}

		public static MessageBoxResult Show( string messageBoxText, string caption, MessageBoxButton button )
		{
			return Show( null, messageBoxText, caption, button );
		}

		public static MessageBoxResult Show( Window owner, string messageBoxText )
		{
			return Show( owner, messageBoxText, "", MessageBoxButton.OK );
		}

		public static MessageBoxResult Show( Window owner, string messageBoxText, string caption, MessageBoxButton button )
		{
			var mbox = new MessageBoxModule();
			mbox.Message = messageBoxText;
			mbox.Title = caption;
			mbox.Owner = owner;

			IsUseCustomInfoDefine( ref mbox );

			if ( owner != null )
			{
				mbox.WindowStartupLocation = WindowStartupLocation.CenterOwner;
			}
			switch ( button )
			{
				case MessageBoxButton.OKCancel:

					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultTrue( mbox, "确定" ) );

					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultFalse( mbox, "取消" ) );
					break;
				//break;
				case MessageBoxButton.YesNo:
					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultTrue( mbox, "是" ) );

					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultFalse( mbox, "否" ) );

					break;
				case MessageBoxButton.YesNoCancel:
					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultTrue( mbox, "是" ) );

					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultFalse( mbox, "否" ) );

					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultFalse( mbox, "取消" ) );
					break;
				case MessageBoxButton.OK:
				default:
					mbox.CtrlButtonCollection.Add( CreateCtrlButton_ResultTrue( mbox, "确定" ) );
					break;
			}
			var result = mbox.ShowDialog();
			switch ( button )
			{

				//break;
				case MessageBoxButton.OKCancel:
					{
						return result == true ? MessageBoxResult.OK
							: result == false ? MessageBoxResult.Cancel :
							MessageBoxResult.None;
					}
				//break;
				case MessageBoxButton.YesNo:
					{
						return result == true ? MessageBoxResult.Yes : MessageBoxResult.No;
					}
				//break;
				case MessageBoxButton.YesNoCancel:
					{
						return result == true ? MessageBoxResult.Yes
							: result == false ? MessageBoxResult.No :
							MessageBoxResult.Cancel;
					}

				case MessageBoxButton.OK:
				default:
					{
						return result == true ? MessageBoxResult.OK : MessageBoxResult.None;
					}
			}
		}

		public static MessageBoxResult Show( Window owner, string messageBoxText, string caption, IList<MessageBoxButtonInfo> ctrlButtons )
		{
			var mbox = new MessageBoxModule();
			mbox.Message = messageBoxText;
			mbox.Title = caption;
			mbox.Owner = owner;

			IsUseCustomInfoDefine( ref mbox );

			if ( owner != null )
			{
				mbox.WindowStartupLocation = WindowStartupLocation.CenterOwner;
			}

			if ( null != ctrlButtons && ctrlButtons.Count > 0 )
			{
				foreach ( var btnInfo in ctrlButtons )
				{
					switch ( btnInfo.Result )
					{
						case MessageBoxResult.Cancel:
						case MessageBoxResult.No:
							{
								var btn = CreateCtrlButton_ResultFalse( mbox, btnInfo.ContentText );
								btn.Command = new MessageBoxCommand( btnInfo.Action );
								mbox.CtrlButtonCollection.Add( btn );
							}
							break;
						case MessageBoxResult.None:
							{
								var btn = CreateCtrlButton_ResultNull( mbox, btnInfo.ContentText );
								btn.Command = new MessageBoxCommand( btnInfo.Action );
								mbox.CtrlButtonCollection.Add( btn );
							}
							break;
						case MessageBoxResult.OK:
						case MessageBoxResult.Yes:
						default:
							{
								var btn = CreateCtrlButton_ResultTrue( mbox, btnInfo.ContentText );
								btn.Command = new MessageBoxCommand( btnInfo.Action );
								mbox.CtrlButtonCollection.Add( btn );
							}
							break;
					}
				}

				var result = mbox.ShowDialog();
				return MessageBoxResult.None;
			}
			else
			{
				return Show( owner, messageBoxText, caption, MessageBoxButton.OK );
			}


		}

		#endregion // Show MessageBox Functions

		#endregion // Public Static Functions

		#region Properties

		public new string Title
		{
			get { return (string)GetValue( TitleProperty ); }
			set { SetValue( TitleProperty, value ); }
		}

		public string Message
		{
			get { return (string)GetValue( MessageProperty ); }
			set { SetValue( MessageProperty, value ); }
		}

		public Brush TitleForeground
		{
			get { return (Brush)GetValue( TitleForegroundProperty ); }
			set { SetValue( TitleForegroundProperty, value ); }
		}

		public IList<Button> CtrlButtonCollection
		{
			get { return (IList<Button>)GetValue( CtrlButtonCollectionProperty ); }
			set { SetValue( CtrlButtonCollectionProperty, value ); }
		}

		#endregion // Properties

		#region Private static functions

		private static Button CreateCtrlButton( string content, RoutedEventHandler clickHandler )
		{
			Button btn = new Button();
			btn.Padding = new Thickness( 20, 3, 20, 3 );
			btn.Content = content;
			btn.ToolTip = content;
			btn.Style = CTRL_BUTTON_STYLE;
			btn.Background = Brushes.Transparent;
			btn.Click += clickHandler;

			return btn;
		}

		private static Button CreateCtrlButton_ResultTrue( MessageBoxModule mbox, string content )
		{
			return CreateCtrlButton( content, new RoutedEventHandler( ( o, e ) =>
			{
				try
				{
					mbox.DialogResult = true;
					
				}
				catch { }
			} ) );
		}

		private static Button CreateCtrlButton_ResultFalse( MessageBoxModule mbox, string content )
		{
			return CreateCtrlButton( content, new RoutedEventHandler( ( o, e ) =>
			{
				try
				{
					mbox.DialogResult = false;
					
				}
				catch { }
			} ) );
		}

		private static Button CreateCtrlButton_ResultNull( MessageBoxModule mbox, string content )
		{
			return CreateCtrlButton( content, new RoutedEventHandler( ( o, e ) =>
			{
				try
				{
					mbox.DialogResult = null;
					
				}
				catch { }
			} ) );
		}

		private static void IsUseCustomInfoDefine( ref MessageBoxModule mbox )
		{
			if ( B_USED_CUSTOM_BRUSHES && null != mbox )
			{
				if ( MB_CUSTOMINFO.IsBackgroundChanged )
				{
					mbox.Background = MB_CUSTOMINFO.MB_Background;
				}
				if ( MB_CUSTOMINFO.IsBorderBrushChanged )
				{
					mbox.BorderBrush = MB_CUSTOMINFO.MB_Borderbrush;
				}
				if ( MB_CUSTOMINFO.IsBorderThicknessChanged )
				{
					mbox.BorderThickness = MB_CUSTOMINFO.MB_BorderThickness;
				}
				if ( MB_CUSTOMINFO.IsForegroundChanged )
				{
					mbox.Foreground = MB_CUSTOMINFO.MB_Foreground;
				}
				if ( MB_CUSTOMINFO.IsTitleForegroundChanged )
				{
					mbox.TitleForeground = MB_CUSTOMINFO.MB_Title_Foreground;
				}
			}
		}

		#endregion // Private static functions

		#region Override functions

		protected override void OnClosed( EventArgs e )
		{
			this.CtrlButtonCollection.Clear();
			base.OnClosed( e );
		}

		#endregion // Override functions
	}

	/// <summary>
	/// Vito.Csharp.Wpf.Controls.MessageBoxModule 组件中 MessageBoxButton 的自定义设置信息.
	/// </summary>
	public class MessageBoxButtonInfo
	{
		#region fields

		private string _contentText = "";
		private MessageBoxResult _result = MessageBoxResult.OK;
		private Action<object> _action = null;

		#endregion // fields

		#region ctor

		/// <summary>
		/// 初始化 MIV.Bus.IEMS.MessageBox 自定义按钮的基本信息.
		/// </summary>
		/// <param name="contentText">按钮的文本内容</param>
		/// <param name="result">按钮响应的返回结果</param>
		/// <param name="action">按钮的响应动作</param>
		public MessageBoxButtonInfo( string contentText, MessageBoxResult result, Action<object> action )
		{
			this._contentText = contentText;
			this._result = result;
			if ( null != action )
			{
				this._action = action;
			}
			else
			{
				this._action = new Action<object>( ( o ) =>
				{

				} );
			}
		}

		#endregion // ctor

		#region Readonly Properties

		/// <summary>
		/// 获取 MIV.Bus.IEMS.MessageBox 按钮的文本内容.
		/// </summary>
		public string ContentText
		{
			get { return _contentText; }
		}

		/// <summary>
		/// 获取 MIV.Bus.IEMS.MessageBox 按钮响应的返回结果.
		/// </summary>
		public MessageBoxResult Result
		{
			get { return _result; }
		}

		/// <summary>
		/// 获取 MIV.Bus.IEMS.MessageBox 按钮的响应动作.
		/// </summary>
		public Action<object> Action
		{
			get { return _action; }
		}

		#endregion // Readonly Properties
	}

	/// <summary>
	/// MIV.Bus.IEMS.MessageBox 自定义信息结构.
	/// </summary>
	public struct MessageBoxCustomInfo
	{
		#region private fields

		private bool isBackgroundChanged;
		private bool isTitleForegroundChanged;
		private bool isForegroundChanged;
		private bool isBorderBrushChanged;
		private bool isBorderThicknessChanged;

		private Brush mb_background;
		private Brush mb_title_foreground;
		private Brush mb_foreground;
		private Brush mb_borderbrush;
		private Thickness mb_borderthickness;

		#endregion // private fields

		#region public properties

		public bool IsBackgroundChanged
		{
			get { return isBackgroundChanged; }
		}
		public bool IsTitleForegroundChanged
		{
			get { return isTitleForegroundChanged; }
		}
		public bool IsForegroundChanged
		{
			get { return isForegroundChanged; }
		}
		public bool IsBorderBrushChanged
		{
			get { return isBorderBrushChanged; }
		}
		public bool IsBorderThicknessChanged
		{
			get { return isBorderThicknessChanged; }
		}


		public Brush MB_Background
		{
			get { return mb_background; }
			set
			{
				mb_background = value;
				isBackgroundChanged = true;
			}
		}
		public Brush MB_Title_Foreground
		{
			get { return mb_title_foreground; }
			set
			{
				mb_title_foreground = value;
				isTitleForegroundChanged = true;
			}
		}
		public Brush MB_Foreground
		{
			get { return mb_foreground; }
			set
			{
				mb_foreground = value;
				isForegroundChanged = true;
			}
		}
		public Brush MB_Borderbrush
		{
			get { return mb_borderbrush; }
			set
			{
				mb_borderbrush = value;
				isBorderBrushChanged = true;
			}
		}
		public Thickness MB_BorderThickness
		{
			get { return mb_borderthickness; }
			set
			{
				mb_borderthickness = value;
				isBorderThicknessChanged = true;
			}
		}

		#endregion // public properties
	}

	/// <summary>
	/// MIV.Bus.IEMS.MessageBoxModule 组件的自定义事件
	/// </summary>
	public class MessageBoxCommand : ICommand
	{
		#region Private Fields
		private readonly Action<object> _command;
		private readonly Func<object, bool> _canExecute;
		#endregion

		#region Constructor
		public MessageBoxCommand( Action<object> command, Func<object, bool> canExecute = null )
		{
			if ( command == null )
				throw new ArgumentNullException( "command" );
			_canExecute = canExecute;
			_command = command;
		}
		#endregion

		#region ICommand Members
		public void Execute( object parameter )
		{
			_command( parameter );
		}
		public bool CanExecute( object parameter )
		{
			if ( _canExecute == null )
				return true;
			return _canExecute( parameter );
		}
		public event EventHandler CanExecuteChanged
		{
			add { CommandManager.RequerySuggested += value; }
			remove { CommandManager.RequerySuggested -= value; }
		}
		#endregion
	}

	/// <summary>
	/// 显示消息框.
	/// </summary>
	public sealed class MessageBox
	{
		#region ctors

		static MessageBox()
		{
		}
		private MessageBox()
		{
		}

		#endregion // ctors

		#region custom settings

		/// <summary>
		/// 设置 MIV.Bus.IEMS.MessageBox 的按钮样式.
		/// </summary>
		/// <param name="buttonStyle"></param>
		public static void SetDefaultCtorButtonStyle( Style buttonStyle )
		{
			MessageBoxModule.SetDefaultCtorButtonStyle( buttonStyle );
		}

		/// <summary>
		/// 设置 MIV.Bus.IEMS.MessageBox 的一些自定义信息.
		/// </summary>
		/// <param name="mbCustomIf">MIV.Bus.IEMS.MessageBox 自定义信息结构</param>
		public static void SetMessageBoxCustomDefine( MessageBoxCustomInfo mbCustomIf )
		{
			MessageBoxModule.SetMessageBoxCustomDefine( mbCustomIf );
		}

		public static void ResetMessageBoxCustomDefine()
		{
			MessageBoxModule.ResetMessageBoxCustomDefine();
		}

		#endregion // custom settings

		#region Show functions

		/// <summary>
		/// 显示一个消息框，该消息框包含消息并返回结果。
		/// </summary>
		/// <param name="messageBoxText">一个 System.String，用于指定要显示的文本。</param>
		/// <returns>一个 System.Windows.MessageBoxResult 值，用于指定用户单击了哪个消息框按钮。</returns>
		public static MessageBoxResult Show( string messageBoxText )
		{
			return MessageBoxModule.Show( messageBoxText );
		}

		/// <summary>
		/// 显示一个消息框，该消息框包含消息和标题栏标题，并且返回结果。
		/// </summary>
		/// <param name="messageBoxText">一个 System.String，用于指定要显示的文本。</param>
		/// <param name="caption"> 一个 System.String，用于指定要显示的标题栏标题。</param>
		/// <returns>一个 System.Windows.MessageBoxResult 值，用于指定用户单击了哪个消息框按钮。</returns>
		public static MessageBoxResult Show( string messageBoxText, string caption )
		{
			return MessageBoxModule.Show( messageBoxText, caption );
		}

		/// <summary>
		/// 显示一个消息框，该消息框包含消息、标题栏标题和按钮，并且返回结果。
		/// </summary>
		/// <param name="messageBoxText">一个 System.String，用于指定要显示的文本。</param>
		/// <param name="caption"> 一个 System.String，用于指定要显示的标题栏标题。</param>
		/// <param name="button">一个 System.Windows.MessageBoxButton 值，用于指定要显示哪个按钮或哪些按钮。</param>
		/// <returns>一个 System.Windows.MessageBoxResult 值，用于指定用户单击了哪个消息框按钮。</returns>
		public static MessageBoxResult Show( string messageBoxText, string caption, MessageBoxButton button )
		{
			return MessageBoxModule.Show( messageBoxText, caption, button );
		}

		/// <summary>
		/// 在指定窗口的前面显示消息框。该消息框显示消息并返回结果。
		/// </summary>
		/// <param name="owner">一个 System.Windows.Window，表示消息框的所有者窗口。</param>
		/// <param name="messageBoxText">一个 System.String，用于指定要显示的文本。</param>
		/// <returns> 一个 System.Windows.MessageBoxResult 值，用于指定用户单击了哪个消息框按钮。</returns>
		public static MessageBoxResult Show( Window owner, string messageBoxText )
		{
			return MessageBoxModule.Show( owner, messageBoxText );
		}

		/// <summary>
		///  在指定窗口的前面显示消息框。该消息框显示消息、标题栏标题和按钮，并且返回结果。
		/// </summary>
		/// <param name="owner"> 一个 System.Windows.Window，表示消息框的所有者窗口。</param>
		/// <param name="messageBoxText">一个 System.String，用于指定要显示的文本。</param>
		/// <param name="caption"> 一个 System.String，用于指定要显示的标题栏标题。</param>
		/// <param name="button">一个 System.Windows.MessageBoxButton 值，用于指定要显示哪个按钮或哪些按钮。</param>
		/// <returns> 一个 System.Windows.MessageBoxResult 值，用于指定用户单击了哪个消息框按钮。</returns>
		public static MessageBoxResult Show( Window owner, string messageBoxText, string caption, MessageBoxButton button )
		{
			return MessageBoxModule.Show( owner, messageBoxText, caption, button );
		}

		/// <summary>
		/// 在指定窗口的前面显示消息框。该消息框显示消息、标题栏标题和按钮，并且支持自定义按钮和动作。
		/// </summary>
		/// <param name="owner"> 一个 System.Windows.Window，表示消息框的所有者窗口。</param>
		/// <param name="messageBoxText">一个 System.String，用于指定要显示的文本。</param>
		/// <param name="caption"> 一个 System.String，用于指定要显示的标题栏标题。</param>
		/// <param name="ctrlButtons">一组自定义的按钮和响应动作。</param>
		/// <returns>始终为 MessageBoxResult.None ,返回结果在此无意义。</returns>
		public static MessageBoxResult Show( Window owner, string messageBoxText, string caption, IList<MessageBoxButtonInfo> ctrlButtons )
		{
			return MessageBoxModule.Show( owner, messageBoxText, caption, ctrlButtons );
		}

		#endregion // Show functions
	} 
		
}
